//
//  ThreadPool.cpp
//
//  Created by 周俊 on 14/12/10.
//
//

#include "ThreadPool.h"

TSP_NS_START

ThreadPool::ThreadPool(size_t size)
    :   m_stop(false)
    , m_finishedTaskNum(0)
    , m_allTaskNum(0)
{
    for(size_t i = 0; i < size; ++i)
    {
        auto thread = [this]
        {
            for(;;)
            {
                std::function<void()> task;
                {
                    //put these code in two braces to make m_queueMutex being unlocked automatically when unique_lock destructing
                    std::unique_lock<std::mutex> lock(this->m_queueMutex);
                    auto predicate = [this]
                    {
                        //线程池结束或者任务队列不为空时, 只能唤醒线程
                        //线程池没有结束并且任务队列为空时, 只能锁定线程
                        return this->m_stop || !this->m_tasks.empty();
                    };

                    //predicate用作线程锁的判断, 只有predicate为false时, wait才会阻塞执行的线程
                    //当线程被唤醒时, 只有predicate为true, 阻塞才会被解除
                    this->m_condition.wait(lock, predicate);

                    if(this->m_stop && this->m_tasks.empty())
                    {
                        return;
                    }

                    task = std::move(this->m_tasks.front());
                    this->m_tasks.pop();
                }

                task();
                this->m_finishedTaskNum += 1;
            }
        };
        m_workers.emplace_back(thread);
    }
}

ThreadPool::~ThreadPool()
{
    {
        //大括号是为了人为给lock创建一个生命周期，m_stop = true执行完毕后自动析构
        std::unique_lock<std::mutex> lock(m_queueMutex);
        m_stop = true;
    }

    
    //唤醒所有执行过m_condition.wait()的线程
    m_condition.notify_all();
    for(std::thread &worker: m_workers)
    {
        worker.join();
    }
}

void ThreadPool::reset()
{
    m_finishedTaskNum = 0;
    m_allTaskNum = 0;
}

TSP_NS_END